/**
 * 
 */
package co.edu.javeriana.ia;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.neuroph.core.NeuralNetwork;

import co.edu.javeriana.ia.neu.Constants;

/**
 * <p>
 * Clase principal que prueba las secuencias
 * </p>
 * 
 * @author <a href=f.triana@javeriana.edu.co">Alejandro Triana</a>
 * @version 1.0
 */
public class Principal {
	
	static int classificationn = 0;

	/**
	 * <p>
	 * Punto principal de ejecucion
	 * </p>
	 */
	public static void main(String[] args) {

		try {
			
			PrintStream print = new PrintStream(new FileOutputStream(
					Constants.FILE_LOG));

			System.setOut(print);

			String testNetwork = System.getProperty("test.onlynetwork");

			if (testNetwork == null) {

				File dirSecuences = new File(Constants.BASE_DIR);
				IOFileFilter filter = new SuffixFileFilter(
						Constants.NEURALFILE_SUFIX);

				Collection<File> filesSequence = FileUtils.listFiles(
						dirSecuences, filter, null);

				for (File file : filesSequence) {

					NeuralNetwork neural = NeuralNetwork
							.load(new FileInputStream(file));

					System.out.println("Test Network Alias: "
							+ neural.getLabel());

					testNeuronalNetwork(neural);
				}
				
			} else {
				
				NeuralNetwork neural = NeuralNetwork
						.load(testNetwork);
				
				testNeuronalNetwork(neural);
				
				System.out.println("Classification: "
						+ classificationn);
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * <p>
	 * Prueba las secuencias sobre la red neuronal
	 * </p>
	 */
	public static void testNeuronalNetwork(NeuralNetwork neural)
			throws IOException {

		File file = new File(Constants.SEQUENCE_TEST_FILE);
		LineIterator iter = FileUtils.lineIterator(file);

		while (iter.hasNext()) {

			String line = (String) iter.next();
			String[] intStr = line.split("\t");

			double[] inDbl = convertArray(intStr);
			neural.setInput(inDbl);

			neural.calculate();

			double[] output = neural.getOutput();
			evaluateOutput(inDbl, output);
		}
	}

	/**
	 * <p>
	 * Convierte el arreglo de String a Double
	 * </p>
	 */
	public static double[] convertArray(String[] inStr) {

		double[] inDbl = new double[Constants.INPUT_SIZE];

		for (int i = 0; i < Constants.INPUT_SIZE; i++) {
			inDbl[i] = Double.parseDouble(inStr[i]);
		}

		return inDbl;
	}

	/**
	 * <p>
	 * Evalua la salida de la red neuronal
	 * </p>
	 */
	public static void evaluateOutput(double[] input, double[] inDbl) {
		
		int realIndex = 0;
		int indexSelected = 0;
		double valueClass = 0.0;
		
		for (int i = 0; i < inDbl.length; i++) {
			if(inDbl[i] == 1) {
				realIndex = i;
				break;
			}
		}
		
		for (int i = 0; i < inDbl.length; i++) {
			
			if(inDbl[i] > valueClass) {
				valueClass = inDbl[i];
				indexSelected = i;
			}
			
			System.out.printf("%f\t", inDbl[i]);
		}
		
		System.out.printf("%d\n", indexSelected + 1);
		
		if( indexSelected == realIndex) {
			classificationn++;
		}
	}

}
